#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
文章与企业相关性判断服务
"""
import json
from typing import Tuple

from openai import OpenAI
from loguru import logger


class RelevanceService:
    """企业相关性判断服务"""
    
    def __init__(self):
        """初始化OpenAI客户端（使用火山引擎）"""
        self.api_key = "sk-18c8e65919e04db690a830f94b30f73c"
        self.base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
        self.llm_id = "qwen3-32b"
        self.enable_reasoning = False
        self.client = OpenAI(api_key=self.api_key, base_url=self.base_url)
    
    def generate_relevance_prompt(self, title: str, content: str, enterprise_info: str) -> str:
        """
        生成相关性判断的提示词
        
        Args:
            title: 文章标题
            content: 文章内容（前500字）
            enterprise_info: 企业信息
            
        Returns:
            str: 提示词
        """
        # 截取文章内容前500字
        content_snippet = content[:500] if content else ""
        
        prompt = f"""你是一个专业的文本相关性分析专家。请评估以下文章与企业的相关性。

企业信息：
{enterprise_info}

文章标题：
{title}

文章内容（前500字）：
{content_snippet}

请分析这篇文章与企业信息的相关性，并给出一个0-100的评分：
- 90-100分：高度相关，文章直接涉及企业的业务、产品、服务或所在行业
- 70-89分：较相关，文章涉及企业关注的领域或相关行业
- 50-69分：一般相关，有一定关联但不是核心内容
- 30-49分：弱相关，仅有间接关联
- 0-29分：不相关，与企业信息无关联

请以JSON格式返回结果，包含以下字段：
- score: 相关性评分（0-100的整数）
- reason: 评分理由（简短说明，不超过100字）
- is_relevant: 是否相关（评分>=70为true，否则为false）

返回格式示例：
{{"score": 85, "reason": "文章讨论了企业所在行业的最新政策法规，与企业业务高度相关", "is_relevant": true}}
"""
        return prompt
    
    def judge_relevance(self, title: str, content: str, enterprise_info: str, 
                       threshold: float = 70.0) -> Tuple[bool, float, str]:
        """
        判断文章与企业的相关性
        
        Args:
            title: 文章标题
            content: 文章内容
            enterprise_info: 企业信息
            threshold: 相关性阈值（默认70分）
            
        Returns:
            Tuple[bool, float, str]: (是否相关, 相关性评分, 理由)
        """
        # 如果企业信息为空，默认不相关
        if not enterprise_info or not enterprise_info.strip():
            logger.info("[relevance_service] 企业信息为空，默认标记为不相关")
            return False, 0.0, "企业信息为空"
        
        # 如果文章标题和内容都为空，默认不相关
        if not title and not content:
            logger.warning("[relevance_service] 文章标题和内容都为空")
            return False, 0.0, "文章内容为空"
        
        try:
            # 生成提示词
            prompt = self.generate_relevance_prompt(title, content, enterprise_info)
            
            # 调用LLM进行判断
            response = self.client.chat.completions.create(
                model=self.llm_id,
                messages=[{"role": "user", "content": prompt}],
                temperature=0.3,
                max_tokens=500,
                response_format={'type': 'json_object'},
                extra_body={"enable_thinking": self.enable_reasoning}
            )
            
            # 解析响应
            result_text = response.choices[0].message.content
            
            # 清理可能的markdown代码块标记
            result_text = result_text.strip()
            if result_text.startswith('```json'):
                result_text = result_text[7:]  # 移除 ```json
            elif result_text.startswith('```'):
                result_text = result_text[3:]  # 移除 ```
            if result_text.endswith('```'):
                result_text = result_text[:-3]  # 移除结尾的 ```
            result_text = result_text.strip()
            
            result = json.loads(result_text)
            
            score = float(result.get('score', 0))
            reason = result.get('reason', '')
            is_relevant = score >= threshold
            
            logger.info(f"[relevance_service] 相关性判断完成: score={score}, is_relevant={is_relevant}, reason={reason}")
            
            return is_relevant, score, reason
            
        except json.JSONDecodeError as e:
            logger.error(f"[relevance_service] JSON解析失败: {e}, response={result_text}")
            return False, 0.0, f"解析失败: {str(e)}"
        except Exception as e:
            logger.error(f"[relevance_service] 相关性判断异常: {e}")
            return False, 0.0, f"判断异常: {str(e)}"
    
    def batch_judge_relevance(self, articles: list, enterprise_info: str, 
                             threshold: float = 70.0) -> list:
        """
        批量判断文章相关性
        
        Args:
            articles: 文章列表，每个文章包含 title 和 content 字段
            enterprise_info: 企业信息
            threshold: 相关性阈值
            
        Returns:
            list: 判断结果列表，每个元素为 (is_relevant, score, reason)
        """
        results = []
        for article in articles:
            title = article.get('title', '')
            content = article.get('content', '')
            result = self.judge_relevance(title, content, enterprise_info, threshold)
            results.append(result)
        return results


def judge_article_relevance(title: str, content: str, enterprise_info: str, 
                            threshold: float = 70.0) -> Tuple[bool, float, str]:
    """
    便捷函数：判断单篇文章与企业的相关性
    
    Args:
        title: 文章标题
        content: 文章内容
        enterprise_info: 企业信息
        threshold: 相关性阈值（默认70分）
        
    Returns:
        Tuple[bool, float, str]: (是否相关, 相关性评分, 理由)
    """
    service = RelevanceService()
    return service.judge_relevance(title, content, enterprise_info, threshold)


if __name__ == '__main__':
    # 测试
    service = RelevanceService()
    
    # 测试文章
    test_title = "交通运输部发布新版《道路运输条例》"
    test_content = "为规范道路运输经营行为，维护道路运输市场秩序，保护道路运输经营者和旅客、托运人的合法权益，促进道路运输业的健康发展，制定本条例。本条例适用于道路旅客运输、道路货物运输、道路运输站场经营等业务..."
    test_enterprise = "某某物流有限公司，主要从事道路货物运输、物流配送等业务"
    
    is_relevant, score, reason = service.judge_relevance(test_title, test_content, test_enterprise)
    print(f"是否相关: {is_relevant}")
    print(f"相关性评分: {score}")
    print(f"评分理由: {reason}")

